
using Youz.Common.Entity;
using Youz.Common.Helper;
using Youz.CreditRepay.DAL;
using Youz.CreditRepay.Entity;
using System;
using System.Data;
using System.Data.SqlClient;
using Youz.Common.BLL;
using System.Text;
using System.Xml;
using System.Threading;
using System.Threading.Tasks;
using Youz.CreditRepay.BLL.Pay;

namespace Youz.CreditRepay.BLL
{
    /// <summary>
    /// Member_Withdraw BLL Class
    /// </summary>
    public partial class Member_WithdrawBLL : BaseBLL
    {
        Member_WithdrawDAL dal;
        Pay_PaymentTypeBLL bllPaymentType = new Pay_PaymentTypeBLL();
        Pay_PaymentType paymentType;
        string v_mid, v_midkey;

        public Member_WithdrawBLL()
        {
            dal = new Member_WithdrawDAL();

            paymentType = bllPaymentType.Get(PaymentType.PayEase.ToString());
            v_mid = paymentType.MerchantNo;
            v_midkey = paymentType.MerchantKey;

            base.ModuleName = "Member_Withdraw";
            base.MenuName = "Member_Withdraw";
        }

        #region  成员方法
        /// <summary>
        /// 生成ID
        /// </summary>
        /// <returns></returns>
        public string GenerateID()
        {
            return dal.GenerateID();
        }

        public bool Add(Member_Withdraw model)
        {
            return dal.Add(model);
        }

        /// <summary>
        /// 提现申请
        /// </summary>
        /// <param name="contract"></param>
        /// <returns></returns>
        public string BalanceWithdraw(string memberAccount, int cardID, decimal WithdrawAmount)
        {
            Member_InfoBLL InfoBLL = new Member_InfoBLL();
            Member_WithdrawAccountBLL WithdrawAccountBLL = new Member_WithdrawAccountBLL();
            Sys_ConfigBLL ConfigBLL = new Sys_ConfigBLL();
            Member_Withdraw withdraw = new Member_Withdraw();
            Member_Account Account = new Member_AccountBLL().Get(memberAccount);

            decimal WithdrawFee = BLL.ConfigParameters.GetCash.GetCashFee;
            decimal totalWithrawAmount = 0;
            decimal usableAmount = Account.Balance;

            if (cardID == 0)
            {
                return Core.AjaxResult(false, "请选择收款银行");
            }
            if (WithdrawAmount <= 0)
            {
                return Utility.AjaxResult(false, "请输入提现金额");
            }
            //检查帐号状态
            if (InfoBLL.Get(memberAccount).Status != MemberStatus.Normal)
            {
                return Utility.AjaxResult(false, "帐号已禁用,无法提现");
            }

            #region 判断过程           
            //提现手续费             
            if (WithdrawAmount == usableAmount)
            {
                WithdrawAmount = WithdrawAmount - WithdrawFee;
            }
            //提现金额+提现手续费
            totalWithrawAmount = WithdrawAmount + WithdrawFee;
            //提现金额+手续费<可用保证金
            if (usableAmount < totalWithrawAmount)
            {
                return Utility.AjaxResult(false, "零钱可用额度不足");
            }
            #endregion

            #region 提现表 赋值
            var card = new CR_BankCardBLL().Get(cardID);

            withdraw.WithdrawID = GenerateID().ToString();
            withdraw.MemberAccount = memberAccount;
            withdraw.Status = WithdrawStatus.Pending;
            withdraw.PayAmount = totalWithrawAmount;
            withdraw.WithdrawAmount = WithdrawAmount;
            withdraw.WithdrawFee = WithdrawFee;
            withdraw.BankCode = card.BankCode;
            withdraw.BankName = card.BankName;
            withdraw.BankAccountName = card.Name;
            withdraw.BankAccountNo = card.CardNo;
            withdraw.MoneyType = "RMB";
            #endregion
            
            var r = dal.Withdraw(withdraw);
            base.WriteOperationLogSensitive(OperationType.Add, r, Core.GetJsonByObjectHaveTime(withdraw), 1, "申请提现");

            if (r)
            {
                return new PPayHelper().Pay(memberAccount, withdraw.WithdrawID, totalWithrawAmount, cardID, cardID, PayTradeType.Withdraw);
            }
            else
            {
                return Utility.AjaxResult(false, "提现失败，系统错误");
            }

        }
        /// <summary>
        /// 撤销提现
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool RevocationWithdraw(Member_Withdraw model, Member_AssetHistory AssetHistory, Sys_StatusRecord recordModel)
        {
            var r = dal.RevocationWithdraw(model, AssetHistory, recordModel);
            base.WriteOperationLogSensitive(OperationType.Update, r, Core.GetJsonByObjectHaveTime(model), 1, "撤销提现");
            // base.WriteOperationLog(OperationType.Update, r, Core.GetJsonByObjectHaveTime(model));

            return r;
        }
        /// <summary>
        ///  审核
        /// </summary>
        public bool Audit(string withdrawID, WithdrawStatus status, string auditOpinion)
        {
            var r = dal.Audit(withdrawID, status, auditOpinion);
            string str = string.Empty;
            if (status == WithdrawStatus.Completed)
            {
                str = "提现通过审核";
                base.WriteOperationLogSensitive(OperationType.Update, r, Core.GetJsonByObjectHaveTime(new { withdrawID=withdrawID, status=status, auditOpinion=auditOpinion }), 1, str);
            }
            else if (status == WithdrawStatus.NotPassed)
            {
                str = "提现未通过审核";
                base.WriteOperationLogSensitive(OperationType.Update, r, Core.GetJsonByObjectHaveTime(new { withdrawID = withdrawID, status = status, auditOpinion = auditOpinion }), 1, str);
            }
            else
            {
                base.WriteOperationLog(OperationType.Update, r, Core.GetJsonByObjectHaveTime(new { withdrawID = withdrawID, status = status, auditOpinion = auditOpinion }));
            }

            return r;
        }
        /// <summary>
        ///  保存一条数据
        /// </summary>
        public bool Update(Member_Withdraw model)
        {
            var r = dal.Update(model);

            base.WriteOperationLog(OperationType.Update, r, Core.GetJsonByObjectHaveTime(model));

            return r;
        }

        public bool Update(string id, WithdrawStatus status)
        {
            bool result = dal.Update(id, status);
            if (status == WithdrawStatus.Submited)
            {
                WriteOperationLogSensitive(OperationType.Update, result, id, 1, "零钱提现");
            }
            else
            {
                WriteOperationLog(OperationType.Update, result, id);
            }

            return result;
        }

        /// <summary>
        /// 删除一条数据
        ///</summary>
        public bool Delete(String WithdrawID)
        {
            var r = dal.Delete(WithdrawID);

            base.WriteOperationLog(OperationType.Delete, r, WithdrawID);

            return r;
        }

        /// <summary>
        /// 得到一个对象实体
        /// </summary>
        public Member_Withdraw Get(String WithdrawID)
        {
            return dal.Get(WithdrawID);
        }

        /// <summary>
        /// 得到一个JSON对象
        /// </summary>
        public string GetJson(String WithdrawID)
        {
            return Core.GetJsonByObjectHaveTime(Get(WithdrawID));
        }

        /// <summary>
        /// 获得数据列表
        /// </summary>
        public DataSet Gets(string sqlWhere)
        {
            return dal.Gets(sqlWhere);
        }

        /// <summary>
        /// 获得前几行数据
        /// </summary>
        public DataSet Gets(int top, string sqlWhere, string filedOrder)
        {
            return dal.Gets(top, sqlWhere, filedOrder);
        }

        /// <summary>
        /// 获取记录总数
        /// </summary>
        public int GetRecordCount(string sqlWhere)
        {
            return dal.GetRecordCount(sqlWhere);
        }
        /// <summary>
        /// 获取提现之和
        /// </summary>
        public decimal GetWithdrawSum(string sqlWhere)
        {
            return dal.GetWithdrawSum(sqlWhere);
        }

        /// <summary>
        /// 获得数据列表分页
        /// </summary>
        public DataTable Gets(string sqlWhere, int pageindex, int pagesize, out int total, params SqlParameter[] cmdParms)
        {
            return dal.Gets(sqlWhere, pageindex, pagesize, out total, cmdParms);
        }
        #endregion  成员方法

        /// <summary>
        /// 按日期统计提现金额和数量
        /// </summary>
        /// <returns></returns>
        public string GetWithdrawChart()
        {
            DataTable dt = dal.GetWithdrawChart();
            return string.Format("[{0},{1}]", TypeHelper.ConvertToChart(dt, 1), TypeHelper.ConvertToChart(dt, 2));
        }

        #region 易支付

        /// <summary>
        /// 获得待处理记录
        /// </summary>
        /// <param name="pageindex"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public DataTable GetPayEaseSubmit(int pageindex, out int total)
        {
            var dt = Gets("a.[Status]=2", pageindex, 1000, out total);

            return dt;
        }

        /// <summary>
        /// 将待处理记录更新为处理中
        /// </summary>
        /// <param name="WithdrawIDs"></param>
        /// <returns></returns>
        public bool SubmitPayEase()
        {
            return dal.SubmitPayEase();
        }

        /// <summary>
        /// 将处理中的记录更新为提交中
        /// </summary>
        /// <param name="startWithdrawID"></param>
        /// <param name="endWithdrawID"></param>
        /// <returns></returns>
        public bool SubmitPayEaseFinish(String startWithdrawID, string endWithdrawID)
        {
            return dal.SubmitPayEaseFinish(startWithdrawID, endWithdrawID);
        }

        /// <summary>
        /// 获取提现状态
        /// </summary>
        /// <param name="withdrawID"></param>
        /// <returns></returns>
        public string GetPayEaseStatus(string withdrawID)
        {
            string v_status = "9";
            string v_desc = "无法连接到远程服务器，返回空";
            string v_mid;
            string v_midkey;
            string v_data;
            string v_mac;
            string v_version;
            string v_fee;
            string paydate = "";
            string transdesc = "";

            var withdraw = Get(withdrawID);

            if (withdraw.Status == WithdrawStatus.Submited)
            {
                var paymentType = new Pay_PaymentTypeBLL().Get(PaymentType.PayEase.ToString());
                v_mid = paymentType.MerchantNo;
                v_midkey = paymentType.MerchantKey;

                v_data = withdrawID;//客户标识编号
                ClassHmac2003.ClassHmac mac = new ClassHmac2003.ClassHmac();
                string key = v_mid + v_data;
                v_mac = mac.hex_hmac_md5(key, v_midkey);//test商户密钥
                v_version = "1.0";
                string url = ConfigParameters.PayEase.GetStatusUrl;//数据状态查询提交地址 pay.yizhifubj.com  
                string postData = "v_mid=" + v_mid + "&v_data=" + v_data + "&v_mac=" + v_mac + "&v_version=" + v_version + "";
                string strBack = WebRequestHelper.GetResponseTextPOST(url, postData);

                if (!string.IsNullOrEmpty(strBack))
                {
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(strBack);
                    v_status = CommonHelper.GetXmlNode(doc, "message/status");
                    v_desc = CommonHelper.GetXmlNode(doc, "message/statusdesc");
                    v_fee = CommonHelper.GetXmlNode(doc, "message/v_fee");
                    paydate = CommonHelper.GetXmlNode(doc, "message/paydate");
                    transdesc = CommonHelper.GetXmlNode(doc, "message/transdesc");

                    switch (v_status)
                    {
                        case "1"://已成功
                            Audit(withdrawID, WithdrawStatus.Completed, "");
                            break;
                        case "3"://已失败
                            Audit(withdrawID, WithdrawStatus.NotPassed, v_desc);
                            break;
                    }

                    DateTime? dtPayDate = null;
                    if (!string.IsNullOrEmpty(paydate))
                    {
                        dtPayDate = DateTime.ParseExact(paydate, "yyyyMMdd HH:mm:ss", System.Globalization.CultureInfo.CurrentCulture);
                    }

                    dal.SavePayEaseLog(withdrawID, TypeHelper.ConvertTo<int>(v_status), v_desc, TypeHelper.ConvertTo<decimal>("0"), null, transdesc);

                    Core.WriteOperationLog("Member_Withdraw", "Status", OperationType.Audit, true, Core.GetJsonByObject(new { status = v_status, desc = v_desc, fee = v_fee, paydate = paydate, transdesc = transdesc }));
                }
            }
            else
            {
                v_desc = "提现申请的当前状态无法查询代付状态";
            }

            return Core.GetJsonByObject(new { status = v_status, desc = v_desc, paydate = paydate, transdesc = transdesc });
        }

        public void GetPayEaseStatusAsyn(string withdrawID)
        {
            Task.Run(() => { GetPayEaseStatus(withdrawID); });
        }

        /// <summary>
        /// 从易支付获取余额
        /// </summary>
        /// <returns></returns>
        public string GetPayEaseBalance()
        {
            string v_status = "1", v_desc = "无法连接到远程服务器，返回空", v_mac, v_balance = "0";
            ClassHmac2003.ClassHmac mac = new ClassHmac2003.ClassHmac();

            v_mac = mac.hex_hmac_md5(v_mid, v_midkey);//test商户密钥

            //string url = "https://pay.yizhifubj.com/merchant/virement/mer_payment_balance_check.jsp";//余额查询
            string url = ConfigParameters.PayEase.GetBalanceUrl;//余额查询 测试地址

            Encoding encoding = Encoding.GetEncoding("utf-8");//GB2312
            string postData1 = "v_mid=" + v_mid + "&v_mac=" + v_mac + "";
            var strBack = WebRequestHelper.GetResponseTextPOST(url, postData1);

            if (!string.IsNullOrEmpty(strBack))
            {
                //XML解析接口返回XML信息为解析信息 
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(strBack);
                v_status = doc.SelectSingleNode("balancemessage/messagehead/status").InnerText;
                v_desc = doc.SelectSingleNode("balancemessage/messagehead/statusdesc").InnerText;

                var nodeMid = doc.SelectSingleNode("balancemessage/messagehead/mid");
                if (nodeMid != null)
                {
                    v_mid = nodeMid.InnerText;
                }

                var nodeBalance = doc.SelectSingleNode("balancemessage/messagebody/balance");
                if (nodeBalance != null)
                {
                    v_balance = nodeBalance.InnerText;
                }
            }

            return Core.GetJsonByObject(new
            {
                status = v_status,
                desc = v_desc,
                mid = v_mid,
                balance = v_balance
            });
        }

        /// <summary>
        /// 提交申请到易支付
        /// </summary>
        /// <returns></returns>
        public string SubmitPayEasePayment()
        {
            string v_data;
            string v_mac;
            string v_version = "1.0";
            string v_status = "1";//状态值
            string v_desc = "无法连接到远程服务器，返回空";//状态值描述
            string batchNo = string.Format("{0}-{1}-{2}", v_mid, DateTime.Now.ToString("yyyyMMdd"), DateTime.Now.ToString("hhmmss"));

            //分帐信息总行数|分帐总金额|批次号$收方帐号|收方帐户名|收方开户行|收方省份|收方城市|付款金额|客户标识|联行号 $收方帐号2
            //注意这个组装写符串中，不要写英文，如果写英文了，请注意大小写问题
            //v_data = "1|0.01|" + batchNo;
            //v_data += "$0000000000000000|户名|银行全称|北京市|北京市|0.01|客户号|银行号";

            StringBuilder sb = new StringBuilder();
            int total = 0;
            decimal totalAmount = 0;
            string startID = "0", endID = "0";

            if (SubmitPayEase())
            {
                DataTable dt = GetPayEaseSubmit(0, out total);

                if (dt.Rows.Count > 0)
                {
                    var i = 0;
                    foreach (DataRow row in dt.Rows)
                    {
                        if (i == 0)
                        {
                            endID = row["WithdrawID"].ToString();
                        }
                        else if (i == 0)
                        {
                            startID = row["WithdrawID"].ToString();
                        }
                        totalAmount += (decimal)row["WithdrawAmount"];
                        sb.AppendFormat("${0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}", row["BankAccountNo"].ToString(), row["BankAccountName"].ToString(), row["BankName"].ToString(), row["BankProvince"].ToString(), row["BankCity"].ToString(), row["WithdrawAmount"].ToString(), row["WithdrawID"].ToString(), row["BankID"].ToString());
                        i++;
                    }
                    sb.Insert(0, string.Format("{0}|{1}|{2}", dt.Rows.Count, totalAmount, batchNo));
                    v_data = sb.ToString();

                    string v_data01 = System.Web.HttpUtility.UrlEncode(v_data, System.Text.Encoding.UTF8).ToUpper();

                    ClassHmac2003.ClassHmac mac = new ClassHmac2003.ClassHmac();
                    string key = v_mid + v_data01;
                    v_mac = mac.hex_hmac_md5(key, v_midkey);//test商户密钥

                    string url = ConfigParameters.PayEase.SubmitUrl; //提交地址  参照接口文档正式提交地址            
                    string postData = "v_mid=" + v_mid + "&v_data=" + v_data + "&v_mac=" + v_mac + "&v_version=" + v_version + "";
                    string strBack = WebRequestHelper.GetResponseTextPOST(url, postData);

                    if (!string.IsNullOrEmpty(strBack))
                    {
                        //XML解析接口返回XML信息为解析信息 
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(strBack);
                        v_status = doc.SelectSingleNode("message/status").InnerText;
                        v_desc = doc.SelectSingleNode("message/statusdesc").InnerText;

                        if (v_status == "0")
                        {
                            SubmitPayEaseFinish(startID, endID);
                        }
                    }
                }
                else
                {
                    v_desc = "没有找到要提交的提现记录";
                }
            }

            return Core.GetJsonByObject(new { status = v_status, desc = v_desc });
        }

        public void AddPayEasePaymentAsyn()
        {
            Task.Run(() => { SubmitPayEasePayment(); });
        }

        /// <summary>
        /// 更新提现记录状态
        /// </summary>
        public void UpdatePayEaseStatus()
        {
            int total;
            DataTable dt = Gets(string.Format(" a.Status = {0} ", (int)WithdrawStatus.Submited), 0, 100, out total);

            foreach (DataRow row in dt.Rows)
            {
                GetPayEaseStatusAsyn(row["WithdrawID"].ToString());
            }
        }
        #endregion
    }
}


